package com.fanw.easyExport.core.data.defaultJdbcImpl;

import com.fanw.easyExport.core.data.DataFetcher;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import javax.sql.DataSource;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * JDBC数据获取器实现
 */
public class JdbcDataFetcher implements DataFetcher,AutoCloseable {
    private final JdbcDataSourceConfig config;
    private DataSource dataSource;

    public JdbcDataFetcher(JdbcDataSourceConfig config) {
        this.config = config;
        initializeDataSource();
    }

    private void initializeDataSource() {
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setDriverClassName(config.getDriverClassName());
        hikariConfig.setJdbcUrl(config.getUrl());
        hikariConfig.setUsername(config.getUsername());
        hikariConfig.setPassword(config.getPassword());

        // 连接池配置
        hikariConfig.setMaximumPoolSize(config.getMaxPoolSize());
        hikariConfig.setMinimumIdle(config.getMinPoolSize());
        hikariConfig.setConnectionTimeout(config.getConnectionTimeout());

        this.dataSource = new HikariDataSource(hikariConfig);
    }

    @Override
    public List<Map<String, Object>> fetchData() {
        List<Map<String, Object>> result = new ArrayList<>();

        try (Connection connection = dataSource.getConnection();
             PreparedStatement statement = connection.prepareStatement(config.getQuery());
             ResultSet resultSet = statement.executeQuery()) {

            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();

            while (resultSet.next()) {
                Map<String, Object> row = new HashMap<>();
                for (int i = 1; i <= columnCount; i++) {
                    String columnName = metaData.getColumnLabel(i);
                    Object value = resultSet.getObject(i);
                    row.put(columnName, value);
                }
                result.add(row);
            }
        } catch (SQLException e) {
            throw new RuntimeException("数据获取失败", e);
        }

        return result;
    }

    // 关闭数据源（在不再需要时调用）
    public void shutdown() {
        if (dataSource instanceof HikariDataSource) {
            ((HikariDataSource) dataSource).close();
        }
    }

    @Override
    public void close() throws Exception {
        shutdown();
    }
}
